from collections import OrderedDict
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination
from rest_framework.response import Response
from rest_framework.utils.urls import replace_query_param, remove_query_param


class CustomPagination(PageNumberPagination):
    page_size = 10    # 表示每页的默认显示数量
    max_page_size = 50  # max_page_size：表示每页最大显示数量，做限制使用，避免突然大量的查询数据，数据库崩溃
    page_size_query_param = 'page_size'   # page_size_query_param：表示url中每页数量参数
    page_query_param = 'page_num'   # page_query_param：表示url中的页码参数

    def get_paginated_response(self, data):
        """
        重构分页返回的数据
        """

        return Response(OrderedDict([
            ('total', self.page.paginator.count),
            ('data', data),
            ('code', 1),
            ('msg', 'success' if data else '暂无数据'),
        ]))


class CustomLimitPagination(LimitOffsetPagination):
    default_limit = 10
    limit_query_param = 'limit'
    offset_query_description = 'offset'
    max_limit = 100

    def get_next_link(self):
        if self.offset + self.limit >= self.count:
            return None

        url = self.request.build_absolute_uri()
        relative_url = self.request.path
        req_params = url.split(relative_url)[-1]
        url = relative_url + req_params
        url = replace_query_param(url, self.limit_query_param, self.limit)

        offset = self.offset + self.limit
        return replace_query_param(url, self.offset_query_param, offset)

    def get_previous_link(self):
        if self.offset <= 0:
            return None

        url = self.request.build_absolute_uri()
        relative_url = self.request.path
        req_params = url.split(relative_url)[-1]
        url = relative_url + req_params
        url = replace_query_param(url, self.limit_query_param, self.limit)

        if self.offset - self.limit <= 0:
            return remove_query_param(url, self.offset_query_param)

        offset = self.offset - self.limit
        return replace_query_param(url, self.offset_query_param, offset)

    def get_paginated_response(self, data):
        return Response(OrderedDict([
            ('total', self.count),
            ('next', self.get_next_link()),
            ('previous', self.get_previous_link()),
            ('data', data),
            ('code', 1),
            ('msg', 'success' if data else '暂无数据'),
        ]))


